﻿@using ZR.CodeGenerator
@using ZR.Model.System.Generate
@using Infrastructure.Extensions;
@* @model ZR.CodeGenerator.Model.GenerateDto; *@
@{
    var genTable = Model.GenTable;
    var subTableOptions = Model.SubTableOptions;
    var options = Model.GenOptions;
    var replaceDto = Model.ReplaceDto;
    var dictHtml = new string[] { GenConstants.HTML_CHECKBOX, GenConstants.HTML_RADIO, GenConstants.HTML_SELECT, GenConstants.HTML_SELECT_MULTI };
    var dicts = new List<GenTableColumn>();
    dicts.AddRange(Model.GenTable.Columns.FindAll((Predicate<GenTableColumn>)(f => dictHtml.Contains(f.HtmlType))));
    if (Model.GenTable.SubTable != null && Model.GenTable.SubTableName.IsNotEmpty())
    {
        dicts.AddRange(Model.GenTable?.SubTable?.Columns?.FindAll((Predicate<GenTableColumn>)(f => dictHtml.Contains(f.HtmlType))));
    }
}
using Infrastructure.Attribute;
using Infrastructure.Extensions;
using @(options.DtosNamespace).@(options.SubNamespace).Dto;
using @(options.ModelsNamespace).@(options.SubNamespace);
using @(options.RepositoriesNamespace);
using @(options.IServicsNamespace).@(options.SubNamespace).I@(options.SubNamespace)Service;
@if(genTable.TplCategory == "tree")
{
    @:using System.Collections.Generic;
}

namespace @(options.ServicesNamespace).@(options.SubNamespace)
{
    /// <summary>
    /// @(genTable.FunctionName)Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(I@(replaceDto.ModelTypeName)Service), ServiceLifetime = LifeTime.Transient)]
    public class @(replaceDto.ModelTypeName)Service : BaseService<@(replaceDto.ModelTypeName)>, I@(replaceDto.ModelTypeName)Service
    {
        /// <summary>
        /// 查询@(genTable.FunctionName)列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<@(replaceDto.ModelTypeName)Dto> GetList(@(replaceDto.ModelTypeName)QueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
@if(null != genTable.SubTableName && "" != genTable.SubTableName)
{
                @://.Includes(x => x.@(genTable.SubTable.ClassName)Nav) //填充子对象
}
@if(genTable.Options.SortField != "" && genTable.Options.SortField != null)
{
                @://.OrderBy("@(genTable.Options.SortField) @(genTable.Options.SortType)")
}
                .Where(predicate.ToExpression())
                .ToPage<@(replaceDto.ModelTypeName), @(replaceDto.ModelTypeName)Dto>(parm);

            return response;
        }

@if(genTable.TplCategory == "tree")
{
        @:/// <summary>
        @:/// 查询@(genTable.FunctionName)树列表
        @:/// </summary>
        @:/// <param name="parm"></param>
        @:/// <returns></returns>
        @:public List<@(replaceDto.ModelTypeName)> GetTreeList(@(replaceDto.ModelTypeName)QueryDto parm)
        @:{
                @:var predicate = Expressionable.Create<@(replaceDto.ModelTypeName)>();

@foreach(var column in genTable.Columns)
{
        if (column.IsQuery)
        {
            if (column.CsharpType == "string")
            {
                @:predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.@(column.CsharpField)), @(CodeGeneratorTool.QueryExp(column.CsharpField, column.QueryType));
            }
            else if (column.CsharpType == "int" || column.CsharpType == "long")
            {
                @:predicate = predicate.AndIF(parm.@(column.CsharpField) != null, @(CodeGeneratorTool.QueryExp(column.CsharpField, column.QueryType));
            }
        }
}

                @:var list = Queryable()
                    @:.Where(predicate.ToExpression())
                    @:.ToList();
                    @:var roots = (from a in list
                            @:join b in list
                            @:on a.@(genTable.Options.TreeParentCode) equals b.@(genTable.Options.TreeCode)
                            @:into join1
                            @:from b in join1.DefaultIfEmpty()
                            @:where b == null
                            @:select a
                         @:).ToList();
                @:foreach(var item in roots)
                @:{
                    @:FillChildren(item, list);
                @:}
                @:return roots;
        @:}

        @:private void FillChildren(@(replaceDto.ModelTypeName) item, List<@(replaceDto.ModelTypeName)> list)
        @:{
            @:item.Children = list.Where(m => m.@(genTable.Options.TreeParentCode) == item.@(genTable.Options.TreeCode)).ToList();
            @:foreach (var sub in item.Children)
            @:{
                @:FillChildren(sub, list);
            @:}
        @:}
}

        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="@(replaceDto.PKName)"></param>
        /// <returns></returns>
        public @(replaceDto.ModelTypeName) GetInfo(@(replaceDto.PKType) @(replaceDto.PKName))
        {
            var response = Queryable()
@if(null != genTable.SubTableName && "" != genTable.SubTableName)
{
                @:.Includes(x => x.@(genTable.SubTable.ClassName)Nav) //填充子对象
}
                .Where(x => x.@(replaceDto.PKName) == @(replaceDto.PKName))
                .First();

            return response;
        }

        /// <summary>
        /// 添加@(genTable.FunctionName)
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public @(replaceDto.ModelTypeName) Add@(replaceDto.ModelTypeName)(@(replaceDto.ModelTypeName) model)
        {
        @if (null != genTable.SubTableName && "" != genTable.SubTableName)
        {
            @:return Context.InsertNav(model).Include(s1 => s1.@(genTable.SubTable.ClassName)Nav).ExecuteReturnEntity();
        }
        else
        {
            if (replaceDto.UseSnowflakeId)
            {
            @:Insertable(model).ExecuteReturnSnowflakeId();
            @:return model;
            }
            else
            {
            @:return Insertable(model).ExecuteReturnEntity();
            }
        }
        }

@if(replaceDto.ShowBtnEdit)
{
        @:/// <summary>
        @:/// 修改@(genTable.FunctionName)
        @:/// </summary>
        @:/// <param name="model"></param>
        @:/// <returns></returns>
        @:public int Update@(replaceDto.ModelTypeName)(@(replaceDto.ModelTypeName) model)
        @:{
@if(null != genTable.SubTableName && "" != genTable.SubTableName)
{
            @:return Context.UpdateNav(model).Include(z1 => z1.@(genTable.SubTable.ClassName)Nav).ExecuteCommand() ? 1 : 0;
}
else
{
            @:return Update(model, true@(replaceDto.EnableLog?$", \"修改{genTable.FunctionName}\"":""));
}
        @:}
@:
}
@if(replaceDto.ShowBtnTruncate)
{
        @:/// <summary>
        @:/// 清空@(genTable.FunctionName)
        @:/// </summary>
        @:/// <returns></returns>
        @:public bool Truncate@(replaceDto.ModelTypeName)()
        @:{
            @:var newTableName = $"@(genTable.TableName)_{DateTime.Now:yyyyMMdd)";
            @:if (Queryable().Any() && !Context.DbMaintenance.IsAnyTable(newTableName))
            @:{
                @:Context.DbMaintenance.BackupTable("@(genTable.TableName)", newTableName);
            @:}
            
            @:return Truncate();
        @:}
}
@if(replaceDto.ShowBtnImport)
{
        @:/// <summary>
        @:/// 导入@(genTable.FunctionName)
        @:/// </summary>
        @:/// <returns></returns>
        @:public (string, object, object) Import@(replaceDto.ModelTypeName)(List<@(replaceDto.ModelTypeName)> list)
        @:{
            @:var x = Context.Storageable(list)
                @:.SplitInsert(it => !it.Any())
    @foreach(var column in genTable.Columns)
    {
        if(column.IsRequired && column.IsIncrement == false)
        {
                @:.SplitError(x => x.Item.@(column.CsharpField).IsEmpty(), "@(column.ColumnComment)不能为空")
        }
    }
                @://.WhereColumns(it => it.UserName)//如果不是主键可以这样实现（多字段it=>new{it.x1,it.x2}）
                @:.ToStorage();
            @:var result = x.AsInsertable.ExecuteCommand();//插入可插入部分;

            @:string msg = $"插入{x.InsertList.Count} 更新{x.UpdateList.Count} 错误数据{x.ErrorList.Count} 不计算数据{x.IgnoreList.Count} 删除数据{x.DeleteList.Count} 总共{x.TotalList.Count}";                    
            @:Console.WriteLine(msg);

            @://输出错误信息               
            @:foreach (var item in x.ErrorList)
            @:{
                @:Console.WriteLine("错误" + item.StorageMessage);
            @:}
            @:foreach (var item in x.IgnoreList)
            @:{
                @:Console.WriteLine("忽略" + item.StorageMessage);
            @:}

            @:return (msg, x.ErrorList, x.IgnoreList);
        @:}

}
@if(replaceDto.ShowBtnExport)
{
        @:/// <summary>
        @:/// 导出@(genTable.FunctionName)
        @:/// </summary>
        @:/// <param name="parm"></param>
        @:/// <returns></returns>
        @:public PagedInfo<@(replaceDto.ModelTypeName)Dto> ExportList(@(replaceDto.ModelTypeName)QueryDto parm)
        @:{
            @:parm.PageNum = 1;
            @:parm.PageSize = 100000;
            @:var predicate = QueryExp(parm);
@:
            @:var response = Queryable()
                @:.Where(predicate.ToExpression())
                @:.Select((it) => new @(replaceDto.ModelTypeName)Dto()
                @:{
@foreach(var column in dicts)
{
    if(column.DictType != "")
    {
                    @:@(column.CsharpField)Label = it.@(column.CsharpField).GetConfigValue<Model.System.SysDictData>("@(column.DictType)"),
    }
}
                @:}, true)
                @:.ToPage(parm);
@:
            @:return response;
        @:}
@:
}
        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<@(replaceDto.ModelTypeName)> QueryExp(@(replaceDto.ModelTypeName)QueryDto parm)
        {
            var predicate = Expressionable.Create<@(replaceDto.ModelTypeName)>();

@foreach(var column in genTable.Columns)
{
    @if(column.IsQuery)
    {
        @if(column.HtmlType == "selectMulti")
        {
                    @:predicate = predicate.AndIF(parm.@(column.CsharpField) != null, it => parm.@(column.CsharpField).Contains(it.@(column.CsharpField)));
        }
        else if(column.CsharpType == "string")
        {
                    @:predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.@(column.CsharpField)), @(CodeGeneratorTool.QueryExp(column.CsharpField, column.QueryType));
        }
        else if(column.CsharpType == "DateTime")
        {
            if(column.HtmlType == "month")
            {
                        @:DateTime monthEnd = Convert.ToDateTime(parm.@(column.CsharpField)).AddMonths(1);
                        @:predicate = predicate.AndIF(parm.@(column.CsharpField) != null, it => it.@(column.CsharpField) >= parm.@(column.CsharpField) && it.@(column.CsharpField) < monthEnd);
            }
            else
            {
                        @:predicate = predicate.AndIF(parm.Begin@(column.CsharpField) == null, it => it.@(column.CsharpField) >= DateTime.Now.ToShortDateString().ParseToDateTime());
                        @:predicate = predicate.AndIF(parm.Begin@(column.CsharpField) != null, it => it.@(column.CsharpField) >= parm.Begin@(column.CsharpField));
                        @:predicate = predicate.AndIF(parm.End@(column.CsharpField) != null, it => it.@(column.CsharpField) <= parm.End@(column.CsharpField));
            }
        }
        else if(column.CsharpType == "int" || column.CsharpType == "long")
        {
                    @:predicate = predicate.AndIF(parm.@(column.CsharpField) != null, @(CodeGeneratorTool.QueryExp(column.CsharpField, column.QueryType));
        }
    }
}
            return predicate;
        }
    }
}